package com.jdy.haoduoai.widget.progressbar;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import com.ycsj.goldmedalnewconcept.R;

//import com.jdy.haoduoai.R;

/**
 *
 * @author zp @ 2015-5-27 下午5:15:53
 */
public class DonutProgress extends View {
  private Paint finishedPaint;
  private Paint unfinishedPaint;
  private Paint innerCirclePaint;
  protected Paint textPaint;
  protected Paint innerBottomTextPaint;

  private final RectF finishedOuterRect = new RectF();
  private final RectF unfinishedOuterRect = new RectF();

  private float textSize;
  private int textColor;
  private int innerBottomTextColor;
  private int progress = 0;
  private int max;
  private int finishedStrokeColor;
  private int unfinishedStrokeColor;
  private float finishedStrokeWidth;
  private float unfinishedStrokeWidth;
  private int innerBackgroundColor;
  private String prefixText = "";
  private String suffixText = "%";
  private String text = null;
  private float innerBottomTextSize;
  private String innerBottomText;
  private float innerBottomTextHeight;

  private final float default_stroke_width;
  private final int default_finished_color = Color.rgb(66, 145, 241);
  private final int default_unfinished_color = Color.rgb(204, 204, 204);
  private final int default_text_color = Color.rgb(66, 145, 241);
  private final int default_inner_bottom_text_color = Color.rgb(66, 145, 241);
  private final int default_inner_background_color = Color.TRANSPARENT;
  private final int default_max = 100;
  private final float default_text_size;
  private final float default_inner_bottom_text_size;
  private final int min_size;

  private static final String INSTANCE_STATE = "saved_instance";
  private static final String INSTANCE_TEXT_COLOR = "text_color";
  private static final String INSTANCE_TEXT_SIZE = "text_size";
  private static final String INSTANCE_TEXT = "text";
  private static final String INSTANCE_INNER_BOTTOM_TEXT_SIZE = "inner_bottom_text_size";
  private static final String INSTANCE_INNER_BOTTOM_TEXT = "inner_bottom_text";
  private static final String INSTANCE_INNER_BOTTOM_TEXT_COLOR = "inner_bottom_text_color";
  private static final String INSTANCE_FINISHED_STROKE_COLOR = "finished_stroke_color";
  private static final String INSTANCE_UNFINISHED_STROKE_COLOR = "unfinished_stroke_color";
  private static final String INSTANCE_MAX = "max";
  private static final String INSTANCE_PROGRESS = "progress";
  private static final String INSTANCE_SUFFIX = "suffix";
  private static final String INSTANCE_PREFIX = "prefix";
  private static final String INSTANCE_FINISHED_STROKE_WIDTH = "finished_stroke_width";
  private static final String INSTANCE_UNFINISHED_STROKE_WIDTH = "unfinished_stroke_width";
  private static final String INSTANCE_BACKGROUND_COLOR = "inner_background_color";

  // public DonutProgress(Context context) {
  // this(context, null);
  // }

  public DonutProgress(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public DonutProgress(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    default_text_size = Utils.sp2px(getResources(), 18);
    min_size = (int) Utils.dp2px(getResources(), 100);
    default_stroke_width = Utils.dp2px(getResources(), 10);
    default_inner_bottom_text_size = Utils.sp2px(getResources(), 18);

    final TypedArray attributes = context.getTheme().obtainStyledAttributes(
        attrs, R.styleable.DonutProgress, defStyleAttr, 0);
    initByAttributes(attributes);
    attributes.recycle();

    initPainters();
  }

  protected void initPainters() {
    textPaint = new TextPaint();
    textPaint.setColor(textColor);
    textPaint.setTextSize(textSize);
    textPaint.setAntiAlias(true);

    innerBottomTextPaint = new TextPaint();
    innerBottomTextPaint.setColor(innerBottomTextColor);
    innerBottomTextPaint.setTextSize(innerBottomTextSize);
    innerBottomTextPaint.setAntiAlias(true);

    finishedPaint = new Paint();
    finishedPaint.setColor(finishedStrokeColor);
    finishedPaint.setStyle(Paint.Style.STROKE);
    finishedPaint.setAntiAlias(true);
    finishedPaint.setStrokeWidth(finishedStrokeWidth);

    unfinishedPaint = new Paint();
    unfinishedPaint.setColor(unfinishedStrokeColor);
    unfinishedPaint.setStyle(Paint.Style.STROKE);
    unfinishedPaint.setAntiAlias(true);
    unfinishedPaint.setStrokeWidth(unfinishedStrokeWidth);

    innerCirclePaint = new Paint();
    innerCirclePaint.setColor(innerBackgroundColor);
    innerCirclePaint.setAntiAlias(true);
  }

  protected void initByAttributes(TypedArray attributes) {
    finishedStrokeColor = attributes.getColor(
        R.styleable.DonutProgress_donut_finished_color, default_finished_color);
    unfinishedStrokeColor = attributes.getColor(
        R.styleable.DonutProgress_donut_unfinished_color,
        default_unfinished_color);
    textColor = attributes.getColor(R.styleable.DonutProgress_donut_text_color,
        default_text_color);
    textSize = attributes.getDimension(
        R.styleable.DonutProgress_donut_text_size, default_text_size);

    setMax(attributes.getInt(R.styleable.DonutProgress_donut_max, default_max));
    setProgress(attributes.getInt(R.styleable.DonutProgress_donut_progress, 0));
    finishedStrokeWidth = attributes.getDimension(
        R.styleable.DonutProgress_donut_finished_stroke_width,
        default_stroke_width);
    unfinishedStrokeWidth = attributes.getDimension(
        R.styleable.DonutProgress_donut_unfinished_stroke_width,
        default_stroke_width);
    if (attributes.getString(R.styleable.DonutProgress_donut_prefix_text) != null) {
      prefixText = attributes
          .getString(R.styleable.DonutProgress_donut_prefix_text);
    }
    if (attributes.getString(R.styleable.DonutProgress_donut_suffix_text) != null) {
      suffixText = attributes
          .getString(R.styleable.DonutProgress_donut_suffix_text);
    }
    if (attributes.getString(R.styleable.DonutProgress_donut_text) != null) {
      text = attributes.getString(R.styleable.DonutProgress_donut_text);
    }
    innerBackgroundColor = attributes.getColor(
        R.styleable.DonutProgress_donut_background_color,
        default_inner_background_color);

    innerBottomTextSize = attributes.getDimension(
        R.styleable.DonutProgress_donut_inner_bottom_text_size,
        default_inner_bottom_text_size);
    innerBottomTextColor = attributes.getColor(
        R.styleable.DonutProgress_donut_inner_bottom_text_color,
        default_inner_bottom_text_color);
    innerBottomText = attributes
        .getString(R.styleable.DonutProgress_donut_inner_bottom_text);
  }

  @Override
  public void invalidate() {
    initPainters();
    super.invalidate();
  }

  public float getFinishedStrokeWidth() {
    return finishedStrokeWidth;
  }

  public void setFinishedStrokeWidth(float finishedStrokeWidth) {
    this.finishedStrokeWidth = finishedStrokeWidth;
    this.invalidate();
  }

  public float getUnfinishedStrokeWidth() {
    return unfinishedStrokeWidth;
  }

  public void setUnfinishedStrokeWidth(float unfinishedStrokeWidth) {
    this.unfinishedStrokeWidth = unfinishedStrokeWidth;
    this.invalidate();
  }

  private float getProgressAngle() {
    return getProgress() / (float) max * 360f;
  }

  public int getProgress() {
    return progress;
  }

  public void setProgress(int progress) {
    this.progress = progress;
    if (this.progress > getMax()) {
      this.progress %= getMax();
    }
    invalidate();
  }

  public int getMax() {
    return max;
  }

  public void setMax(int max) {
    if (max > 0) {
      this.max = max;
      invalidate();
    }
  }

  public float getTextSize() {
    return textSize;
  }

  public void setTextSize(float textSize) {
    this.textSize = textSize;
    this.invalidate();
  }

  public int getTextColor() {
    return textColor;
  }

  public void setTextColor(int textColor) {
    this.textColor = textColor;
    this.invalidate();
  }

  public int getFinishedStrokeColor() {
    return finishedStrokeColor;
  }

  public void setFinishedStrokeColor(int finishedStrokeColor) {
    this.finishedStrokeColor = finishedStrokeColor;
    this.invalidate();
  }

  public int getUnfinishedStrokeColor() {
    return unfinishedStrokeColor;
  }

  public void setUnfinishedStrokeColor(int unfinishedStrokeColor) {
    this.unfinishedStrokeColor = unfinishedStrokeColor;
    this.invalidate();
  }

  public String getText() {
    return text;
  }

  public void setText(String text) {
    this.text = text;
    this.invalidate();
  }

  public String getSuffixText() {
    return suffixText;
  }

  public void setSuffixText(String suffixText) {
    this.suffixText = suffixText;
    this.invalidate();
  }

  public String getPrefixText() {
    return prefixText;
  }

  public void setPrefixText(String prefixText) {
    this.prefixText = prefixText;
    this.invalidate();
  }

  public int getInnerBackgroundColor() {
    return innerBackgroundColor;
  }

  public void setInnerBackgroundColor(int innerBackgroundColor) {
    this.innerBackgroundColor = innerBackgroundColor;
    this.invalidate();
  }

  public String getInnerBottomText() {
    return innerBottomText;
  }

  public void setInnerBottomText(String innerBottomText) {
    this.innerBottomText = innerBottomText;
    this.invalidate();
  }

  public float getInnerBottomTextSize() {
    return innerBottomTextSize;
  }

  public void setInnerBottomTextSize(float innerBottomTextSize) {
    this.innerBottomTextSize = innerBottomTextSize;
    this.invalidate();
  }

  public int getInnerBottomTextColor() {
    return innerBottomTextColor;
  }

  public void setInnerBottomTextColor(int innerBottomTextColor) {
    this.innerBottomTextColor = innerBottomTextColor;
    this.invalidate();
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));

    // TODO calculate inner circle height and then position bottom text at the
    // bottom (3/4)
    innerBottomTextHeight = getHeight() - (getHeight() * 3) / 4;
  }

  private int measure(int measureSpec) {
    int result;
    int mode = MeasureSpec.getMode(measureSpec);
    int size = MeasureSpec.getSize(measureSpec);
    if (mode == MeasureSpec.EXACTLY) {
      result = size;
    } else {
      result = min_size;
      if (mode == MeasureSpec.AT_MOST) {
        result = Math.min(result, size);
      }
    }
    return result;
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    float delta = Math.max(finishedStrokeWidth, unfinishedStrokeWidth);
    finishedOuterRect
        .set(delta, delta, getWidth() - delta, getHeight() - delta);
    unfinishedOuterRect.set(delta, delta, getWidth() - delta, getHeight()
        - delta);

    float innerCircleRadius = (getWidth()
        - Math.min(finishedStrokeWidth, unfinishedStrokeWidth) + Math
        .abs(finishedStrokeWidth - unfinishedStrokeWidth)) / 2f;
    canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, innerCircleRadius,
        innerCirclePaint);
    canvas.drawArc(finishedOuterRect, -90, getProgressAngle(), false,
        finishedPaint);
    canvas.drawArc(unfinishedOuterRect, getProgressAngle() - 90,
        360 - getProgressAngle(), false, unfinishedPaint);

    String text = this.text != null ? this.text : prefixText + progress
        + suffixText;
    if (!TextUtils.isEmpty(text)) {
      float textHeight = textPaint.descent() + textPaint.ascent();
      canvas.drawText(text, (getWidth() - textPaint.measureText(text)) / 2.0f,
          (getWidth() - textHeight) / 2.0f, textPaint);
    }

    if (!TextUtils.isEmpty(getInnerBottomText())) {
      innerBottomTextPaint.setTextSize(innerBottomTextSize);
      float bottomTextBaseline = getHeight() - innerBottomTextHeight
          - (textPaint.descent() + textPaint.ascent()) / 2;
      canvas
          .drawText(getInnerBottomText(), (getWidth() - innerBottomTextPaint
              .measureText(getInnerBottomText())) / 2.0f, bottomTextBaseline,
              innerBottomTextPaint);
    }

  }

  @Override
  protected Parcelable onSaveInstanceState() {
    final Bundle bundle = new Bundle();
    bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
    bundle.putInt(INSTANCE_TEXT_COLOR, getTextColor());
    bundle.putFloat(INSTANCE_TEXT_SIZE, getTextSize());
    bundle.putFloat(INSTANCE_INNER_BOTTOM_TEXT_SIZE, getInnerBottomTextSize());
    bundle
        .putFloat(INSTANCE_INNER_BOTTOM_TEXT_COLOR, getInnerBottomTextColor());
    bundle.putString(INSTANCE_INNER_BOTTOM_TEXT, getInnerBottomText());
    bundle.putInt(INSTANCE_INNER_BOTTOM_TEXT_COLOR, getInnerBottomTextColor());
    bundle.putInt(INSTANCE_FINISHED_STROKE_COLOR, getFinishedStrokeColor());
    bundle.putInt(INSTANCE_UNFINISHED_STROKE_COLOR, getUnfinishedStrokeColor());
    bundle.putInt(INSTANCE_MAX, getMax());
    bundle.putInt(INSTANCE_PROGRESS, getProgress());
    bundle.putString(INSTANCE_SUFFIX, getSuffixText());
    bundle.putString(INSTANCE_PREFIX, getPrefixText());
    bundle.putString(INSTANCE_TEXT, getText());
    bundle.putFloat(INSTANCE_FINISHED_STROKE_WIDTH, getFinishedStrokeWidth());
    bundle.putFloat(INSTANCE_UNFINISHED_STROKE_WIDTH,
        getUnfinishedStrokeWidth());
    bundle.putInt(INSTANCE_BACKGROUND_COLOR, getInnerBackgroundColor());
    return bundle;
  }

  @Override
  protected void onRestoreInstanceState(Parcelable state) {
    if (state instanceof Bundle) {
      final Bundle bundle = (Bundle) state;
      textColor = bundle.getInt(INSTANCE_TEXT_COLOR);
      textSize = bundle.getFloat(INSTANCE_TEXT_SIZE);
      innerBottomTextSize = bundle.getFloat(INSTANCE_INNER_BOTTOM_TEXT_SIZE);
      innerBottomText = bundle.getString(INSTANCE_INNER_BOTTOM_TEXT);
      innerBottomTextColor = bundle.getInt(INSTANCE_INNER_BOTTOM_TEXT_COLOR);
      finishedStrokeColor = bundle.getInt(INSTANCE_FINISHED_STROKE_COLOR);
      unfinishedStrokeColor = bundle.getInt(INSTANCE_UNFINISHED_STROKE_COLOR);
      finishedStrokeWidth = bundle.getFloat(INSTANCE_FINISHED_STROKE_WIDTH);
      unfinishedStrokeWidth = bundle.getFloat(INSTANCE_UNFINISHED_STROKE_WIDTH);
      innerBackgroundColor = bundle.getInt(INSTANCE_BACKGROUND_COLOR);
      initPainters();
      setMax(bundle.getInt(INSTANCE_MAX));
      setProgress(bundle.getInt(INSTANCE_PROGRESS));
      prefixText = bundle.getString(INSTANCE_PREFIX);
      suffixText = bundle.getString(INSTANCE_SUFFIX);
      text = bundle.getString(INSTANCE_TEXT);
      super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
      return;
    }
    super.onRestoreInstanceState(state);
  }
}
